// Copyright Epic Games, Inc. All Rights Reserved.

#include "LyraAbilityCost_ItemTagStack.h" // 包含头文件

#include "Equipment/LyraGameplayAbility_FromEquipment.h" // 包含装备相关能力头文件
#include "Inventory/LyraInventoryItemInstance.h" // 包含库存物品实例头文件
#include "NativeGameplayTags.h" // 包含原生游戏标签头文件

#include UE_INLINE_GENERATED_CPP_BY_NAME(LyraAbilityCost_ItemTagStack) // 包含自动生成的代码

UE_DEFINE_GAMEPLAY_TAG(TAG_ABILITY_FAIL_COST, "Ability.ActivateFail.Cost"); // 定义游戏标签：能力激活失败-消耗

/**
 * 构造函数，初始化默认值
 */
ULyraAbilityCost_ItemTagStack::ULyraAbilityCost_ItemTagStack()
{
	Quantity.SetValue(1.0f); // 设置默认消耗数量为1.0
	FailureTag = TAG_ABILITY_FAIL_COST; // 设置默认失败标签
}

/**
 * 检查能力消耗是否满足
 * @param Ability 游戏能力对象
 * @param Handle 能力规格句柄
 * @param ActorInfo 演员信息
 * @param OptionalRelevantTags 可选的相关标签容器
 * @return 是否满足消耗条件
 */
bool ULyraAbilityCost_ItemTagStack::CheckCost(const ULyraGameplayAbility* Ability, const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, FGameplayTagContainer* OptionalRelevantTags) const
{
	if (const ULyraGameplayAbility_FromEquipment* EquipmentAbility = Cast<const ULyraGameplayAbility_FromEquipment>(Ability)) // 尝试将能力转换为装备能力
	{
		if (ULyraInventoryItemInstance* ItemInstance = EquipmentAbility->GetAssociatedItem()) // 获取关联的物品实例
		{
			const int32 AbilityLevel = Ability->GetAbilityLevel(Handle, ActorInfo); // 获取能力等级

			const float NumStacksReal = Quantity.GetValueAtLevel(AbilityLevel); // 根据能力等级获取消耗数量（浮点数）
			const int32 NumStacks = FMath::TruncToInt(NumStacksReal); // 将浮点数转换为整数
			const bool bCanApplyCost = ItemInstance->GetStatTagStackCount(Tag) >= NumStacks; // 检查物品实例的标签堆叠数量是否足够

			// 如果无法应用消耗且有可选标签容器且失败标签有效，则添加失败标签
			if (!bCanApplyCost && OptionalRelevantTags && FailureTag.IsValid())
			{
				OptionalRelevantTags->AddTag(FailureTag); // 添加失败标签到容器
			}
			return bCanApplyCost; // 返回是否满足消耗条件
		}
	}
	return false; // 如果转换失败或物品实例为空，返回false
}

/**
 * 应用能力消耗
 * @param Ability 游戏能力对象
 * @param Handle 能力规格句柄
 * @param ActorInfo 演员信息
 * @param ActivationInfo 能力激活信息
 */
void ULyraAbilityCost_ItemTagStack::ApplyCost(const ULyraGameplayAbility* Ability, const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo)
{
	if (ActorInfo->IsNetAuthority()) // 检查是否在网络权威端
	{
		if (const ULyraGameplayAbility_FromEquipment* EquipmentAbility = Cast<const ULyraGameplayAbility_FromEquipment>(Ability)) // 尝试将能力转换为装备能力
		{
			if (ULyraInventoryItemInstance* ItemInstance = EquipmentAbility->GetAssociatedItem()) // 获取关联的物品实例
			{
				const int32 AbilityLevel = Ability->GetAbilityLevel(Handle, ActorInfo); // 获取能力等级

				const float NumStacksReal = Quantity.GetValueAtLevel(AbilityLevel); // 根据能力等级获取消耗数量（浮点数）
				const int32 NumStacks = FMath::TruncToInt(NumStacksReal); // 将浮点数转换为整数

				ItemInstance->RemoveStatTagStack(Tag, NumStacks); // 从物品实例中移除指定数量的标签堆叠
			}
		}
	}
}